<?php
//   +----------------------------------------------------------------------
//   | Copyright (c) 2015-2025 http://www.hdphp.cn All rights reserved.
//   | Licensed ( http://www.hdphp.cn/licenses/ )
//   | Author: Jack <sophia2152@qq.com>
//   | 官方网址: http://www.hdphp.cn
//   | 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用。
//   | 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
//   +----------------------------------------------------------------------
namespace app\services\system;

use app\dao\system\SystemRoleDao;
use app\Request;
use app\services\BaseServices;
use hdphp\exceptions\AuthException;
use hdphp\services\CacheService;

/**
 * Class：系统角色服务
 * 创建人：Jack
 * 创建时间：2023/7/29 7:36 PM
 * @package app\services\system
 * @mixin SystemRoleDao
 */
class SystemRoleServices extends BaseServices
{

    /**
     * 当前管理员权限缓存前缀
     */
    const ADMIN_RULES_LEVEL = 'Admin_rules_level_';

    /**
     * SystemRoleServices constructor.
     * @param SystemRoleDao $dao
     */
    public function __construct(SystemRoleDao $dao)
    {
        $this->dao = $dao;
    }

    /**
     * 注释：角色列表
     * 创建人：Jack
     * 创建时间：2023/8/1 9:15
     * @param array $where
     * @return array
     */
    public function getRoleList(array $where)
    {
        [$page, $limit] = $this->getPageValue();
        $list = $this->dao->getRouleList($where, $page, $limit);
        $count = $this->dao->count($where);
        /** @var SystemMenusServices $service */
        $service = app()->make(SystemMenusServices::class);
        foreach ($list as &$item) {
            $item['rules_name'] = implode(',', array_merge($service->column(['id' => $item['rules']], 'menu_name', 'id')));
            $item['checked_menus'] = $item['rules'] ? array_map('intval', explode(',', $item['rules'])) : [];
        }

        return compact('count', 'list');
    }

    /**
     * 注释：获取权限
     * 创建人：Jack
     * 创建时间：2023/7/29 7:40 PM
     * @param array  $where
     * @param string $field
     * @param string $key
     * @return array
     */
    public function getRoleArray(array $where = [], string $field = '', string $key = '')
    {
        return $this->dao->getRoule($where, $field, $key);
    }

    /**
     * 注释：系统验证权限
     * 创建人：Jack
     * 创建时间：2023/7/30 14:53
     * @param Request $request
     * @return true|void
     */
    public function verifyAuth(Request $request)
    {
        // 获取当前的接口于接口类型
        $rule = trim(strtolower($request->rule()->getRule()));
        $method = trim(strtolower($request->method()));
        // 判断接口是一下两种的时候放行
        if (in_array($rule, ['setting/admin/logout', 'menuslist'])) {
            return true;
        }
        $auth = $this->getAllRoles(2);
        // 验证访问接口是否存在
        if (!in_array($method . '@@' . $rule, array_map(function ($item) {
            return trim(strtolower($item['methods'])) . '@@' . trim(strtolower(str_replace(' ', '', $item['api_url'])));
        }, $auth))) {
            return true;
        }
        $auth = $this->getRolesByAuth($request->adminInfo()['roles'], 2);
        // 验证访问接口是否有权限
        if ($auth && empty(array_filter($auth, function ($item) use ($rule, $method) {
                if (trim(strtolower($item['api_url'])) === $rule && $method === trim(strtolower($item['methods'])))
                    return true;
            }))) {
            throw new AuthException(110000);
        }
    }

    /**
     * 注释：获取所有权限
     * 创建人：Jack
     * 创建时间：2023/7/30 14:28
     * @param int    $auth_type
     * @param string $cachePrefix
     * @return mixed
     */
    public function getAllRoles(int $auth_type = 1, string $cachePrefix = self::ADMIN_RULES_LEVEL)
    {
        $cacheName = md5($cachePrefix . '_' . $auth_type . '_ALl');
        return CacheService::redisHandler('system_menus')->remember($cacheName, function () use ($auth_type) {
            /** @var SystemMenusServices $menusService */
            $menusService = app()->make(SystemMenusServices::class);
            return $menusService->getColumn([['auth_type', '=', $auth_type]], 'api_url,methods');
        });
    }

    /**
     * 注释：获取指定权限
     * 创建人：Jack
     * 创建时间：2023/7/30 14:36
     * @param array  $roles
     * @param int    $auth_type
     * @param string $cachePrefix
     * @return array|mixed
     */
    public function getRolesByAuth(array $roles, int $auth_type = 1, string $cachePrefix = self::ADMIN_RULES_LEVEL)
    {
        if (empty($roles)) return [];
        $cacheName = md5($cachePrefix . '_' . $auth_type . '_' . implode('_', $roles));
        return CacheService::redisHandler('system_menus')->remember($cacheName, function () use ($roles, $auth_type) {
            /** @var SystemMenusServices $menusService */
            $menusService = app()->make(SystemMenusServices::class);
            return $menusService->getColumn([['id', 'IN', $this->getRoleIds($roles)], ['auth_type', '=', $auth_type]], 'api_url,methods');
        });
    }

    /**
     * 注释：获取权限id
     * 创建人：Jack
     * 创建时间：2023/7/30 14:37
     * @param array  $roles
     * @param string $field
     * @param string $key
     * @return array|string[]
     */
    public function getRoleIds(array $roles, string $field = 'rules', string $key = 'id')
    {
        $rules = $this->dao->getColumn([['id', 'IN', $roles], ['status', '=', '1']], $field, $key);
        return $rules ? array_unique(explode(',', implode(',', $rules))) : [];
    }

    /**
     * 注释：getAllRoleList
     * 创建人：Jack
     * 创建时间：2023/8/10 15:52
     * @param array $where
     * @return array
     */
    public function getAllRoleList(array $where)
    {
        $roleList = $this->dao->getAllRoleList($where, ['id as value', 'role_name as label']);
        return $roleList ?? [];
    }

}